/**
 * Copyright (c) 2018-2022, NXOS Development Team
 * SPDX-License-Identifier: Apache-2.0
 * 
 * Contains: stack backtrace
 * 
 * Change Logs:
 * Date           Author            Notes
 * 2022-07-27     JasonHu           Init
 */

#ifndef __DEBUG_BACKTRACE_H__
#define __DEBUG_BACKTRACE_H__

#include <nxos_mini.h>

/* default stack backtrace depth */
#define NX_BACKTRACE_DEPTH_DEFAULT 16 

struct NX_StackBacktraceOps
{
    NX_Size (*backtrace)(void ** buffer, NX_Size size, NX_Addr fp, NX_Addr stackTop);
};

NX_INTERFACE NX_IMPORT struct NX_StackBacktraceOps gStackBacktraceOpsInterface;

/**
 * @brief backtrace the call stack 
 * 
 * @param buffer the addr buffer array addr to store the call stack
 * @param size length of the max buffer array size
 * @param fp stack frame pointer, if zero, get current fp
 * @param stkTop stack top of this backtrace
 * 
 * @return (NX_Size) the real stack backtrace buffer len
 */
#define NX_StackBacktrace(buffer, size, fp, stkTop) gStackBacktraceOpsInterface.backtrace(buffer, size, fp, stkTop)

NX_Error NX_StackBacktracePrint(void ** buffer, NX_Size size);

/**
 * @brief do stack backtrace with raw args and print call path here
 * 
 * @param fp stack frame pointer, if zero, get current fp
 * @param stkTop stack top of this backtrace
 */
#define NX_BTRACE_RAW(fp, stkTop) \
    do { \
        void * buf[NX_BACKTRACE_DEPTH_DEFAULT] = {0}; \
        NX_Size n = NX_StackBacktrace(buf, NX_BACKTRACE_DEPTH_DEFAULT, fp, stkTop); \
        NX_StackBacktracePrint(buf, n); \
    } while (0)

/**
 * @brief do stack backtrace and print call path here,
 *          NX_BTRACE_RAW(0,0) means backtrace on current fp, no stack top limit.
 */
#define NX_BTRACE() \
    NX_BTRACE_RAW(0, 0)

#endif /* __DEBUG_BACKTRACE_H__ */
